from django.views import View
from django.http import JsonResponse
from django.conf import settings
from django.db import transaction
from datetime import datetime
import logging
import json

from IHome.utils.errmsg_info import error_no, error_msg
from homes.models import Area, House, HouseImage, Facility
from orders.models import Order
from IHome.utils.mixin import login_decorator, LoginRequiredJsonMixin
from IHome.libs.qiniuyun.qiniu_storage import storage

# Create your views here.

# 创建日志生成器
logger = logging.getLogger('django')





class HouseDetailView(View):
    """房屋详情页面
    api/v1.0/houses/[int:house_id]
    """
    def get(self, request, house_id):

        house = House.objects.get(id=house_id)
        # order = Order.objects.get(user=request.user)
        # ctime = datetime.strftime(order.create_time, '%Y-%m-%d %H:%M:%S')
        comments = []
        facilities = [facility.id for facility in house.facility.all()]
        img_urls = [settings.QINIU_URL + h_img.url for h_img in HouseImage.objects.filter(house_id=house_id)]
        house_dict = {
            'acreage': house.acreage,
            'address': house.address,
            'beds': house.beds,
            'capacity': house.capacity,
            'comments': comments,
            'deposit': house.deposit,
            'facilities': facilities,
            'hid': house_id,  # 注意
            'img_urls': img_urls,
            'max_days': house.max_days,
            'min_days': house.min_days,
            'price': house.price,
            'room_count': house.room_count,
            'title': house.title,
            'unit': house.unit,
            'user_avatar': settings.QINIU_URL + str(house.user.avatar),
            'user_id': house.user.id,
            'user_name': house.user.username
        }

        data = {
            'house': house_dict,
            # 没登录返回-1
            'user_id': request.user.id or -1
        }

        return JsonResponse({'errno': error_no['OK'],
                             'errmsg': error_msg['OK'],
                             'data': data})


class IndexImageView(View):
    """首页房屋推荐"""
    def get(self, request):
        data = []
        # 查询集是个列表,可以使用切片,可以考虑使用分页
        houses = House.objects.all().order_by('-create_time')[:5]
        for house in houses:
            data.append({
                'house_id': house.id,
                'img_url': settings.QINIU_URL + house.index_image_url,
                'title': house.title
            })

        return JsonResponse({'errno': error_no['OK'],
                             'errmsg': error_msg['OK'],
                             'data': data})


class UploadHouseImage(LoginRequiredJsonMixin, View):
    """上传房屋图片"""
    def post(self, request, house_id):
        file_data = request.FILES.get('house_image')
        try:
            key = storage(file_data.read())
        except Exception as e:
            logger.error(e)

        House.objects.filter(id=house_id).update(index_image_url=key)
        HouseImage.objects.create(
            house_id=house_id, url=key)

        data = {
            'url': settings.QINIU_URL + key
        }
        return JsonResponse({'errno': error_no['OK'],
                             'errmsg': '图片上传成功',
                             'data': data})


class ShowHouseListView(LoginRequiredJsonMixin, View):
    """房屋列表
    api/v1.0/user/houses
    """
    def get(self, request):
        house_list = []   # [{}, {}, ..]
        houses = House.objects.filter(user=request.user).order_by('-create_time')

        for house in houses:

            # 既然是遍历出来的,数据肯定存在,就不需要捕获异常了
            h_img = HouseImage.objects.get(house=house)
            # strftime把时间转化成字符串'2018-1-2'
            # datetime.strftime(house.create_time, '%Y-%m-%d') 还是datetime类型 效果'2018-1-2 00:00:00'
            ctime = datetime.strftime(house.create_time, '%Y-%m-%d')

            house_list.append({
                'address': house.address,
                'area_name': house.area.name,
                'ctime': ctime,
                'house_id': house.id,
                'img_url': settings.QINIU_URL + h_img.url,
                'order_count': house.order_count,
                'price': house.price,
                'room_count': house.room_count,
                'title': house.title,
                'user_avatar': settings.QINIU_URL + str(request.user.avatar)
            })
        data = {
            'houses': house_list
        }

        return JsonResponse({'errno': error_no['OK'],
                             'errmsg': error_msg['OK'],
                             'data': data})


class LaunchHouseSourceView(LoginRequiredJsonMixin, View):
    """发布房源
    api/v1.0/houses
    """
    def post(self, request):
        """发布房源"""
        # 提取参数
        json_dict = json.loads(request.body.decode())
        title = json_dict.get('title')
        price = json_dict.get('price')
        area_id = json_dict.get('area_id')
        address = json_dict.get('address')
        room_count = json_dict.get('room_count')
        acreage = json_dict.get('acreage')
        unit = json_dict.get('unit')
        capacity = json_dict.get('capacity')
        beds = json_dict.get('beds')
        deposit = json_dict.get('deposit')
        min_days = json_dict.get('min_days')
        max_days = json_dict.get('max_days')
        facility_list = json_dict.get('facility')

        # 校验参数
        if not all([title, price, area_id, address, room_count, acreage, unit, capacity,
                    beds, deposit, min_days, max_days, facility_list]):
            return JsonResponse({'errno': error_no['PARAMERR'],
                                 'errmsg': '缺少必要参数'})

        # 使用事务保证两个表的一致性,要么一起保存,要么一起不保存
        with transaction.atomic():
            # 创建保存点
            save_id = transaction.savepoint()
            try:
                house = House.objects.create(
                    user=request.user,
                    area_id=area_id,
                    title=title,
                    price=price,
                    address=address,
                    room_count=room_count,
                    acreage=acreage,
                    unit=unit,
                    capacity=capacity,
                    beds=beds,
                    deposit=deposit,
                    min_days=min_days,
                    max_days=max_days,
                )
            except Exception as e:
                logger.error(e)
                # 回滚到保存点
                # transaction.savepoint_rollback(save_id)
                return JsonResponse({'errno': error_no['DBERR'],
                                 'errmsg': '数据保存到数据库失败'})

            # 多对多,保存新数据到中间表中
            facilities = Facility.objects.filter(id__in=facility_list)
            for facility in facilities:
                try:
                    house.facility.add(facility)
                except Exception as e:
                    logger.error(e)
                    # 回滚到保存点
                    transaction.savepoint_rollback(save_id)
                    return JsonResponse({'errno': error_no['DBERR'],
                                         'errmsg': '数据保存到数据库失败'})

            # 取消保存点
            transaction.savepoint_commit(save_id)

        return JsonResponse({'errno': error_no['OK'],
                             'errmsg': '发布成功',
                             'data': {'house_id': house.id}})


class ShowAreaView(View):
    """城区列表
    api/v1.0/areas
    """
    def get(self, request):
        data = []   # [{}, {}, ....]
        areas = Area.objects.all()
        for area in areas:
            data.append({
                'aid': area.id,
                'aname': area.name
            })

        return JsonResponse({'errno': error_no['OK'],
                             'errmsg': '获取成功',
                             'data': data})



